package persistence;

import model.*;

import javax.persistence.*;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: david
 * Date: 8/9/13
 * Time: 2:29 PM
 * To change this template use File | Settings | File Templates.
 */
public class Storage {
    private static final String PERSISTENCE_UNIT_NAME = "laminator";


    private static EntityManager getEntityManager(){
        EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        return factory.createEntityManager();
    }

    public static void storeLaminaat(Laminaat l){
        if(l != null){
            store(l);
        }
    }

    public static void updateFiber(Fiber f){
        if(f != null){
            update(f);
        }
    }

    public static List<Laminaat> getAllLaminaat(){
        return getAllOfClass(Laminaat.class);
    }

    public static void storeEpoxy(Epoxy e){
        if(e != null){
            store(e);
        }
    }

    public static List<Epoxy> getAllEpoxy(){
        return getAllOfClass(Epoxy.class);
    }

    public static void storeLamel(Lamel l){
        if(l != null){
            store(l);
        }
    }

    public static List<Lamel> getAllLamel(){
        return getAllOfClass(Lamel.class);
    }

    public static List<Fiber> getAllFibers(){
        return getAllOfClass(Fiber.class);
    }

    public static void storeFiber(Fiber fiber){
        if(fiber != null){
            store(fiber);
        }
    }


    /**
     * Returns all objects of Type {@code T}
     *
     * Required is that the base class should be defined in persistence.xml, as noted in PersistableInterface.
     *
     * @param c the base class to all objects from
     * @param <T>
     * @return
     */
    private static <T extends PersistableInterface> List<T> getAllOfClass(Class<T> c){
        EntityManager em = getEntityManager();
        TypedQuery<T> tq = em.createQuery("select x from "+c.getName()+" x",c);
        List<T> ret = tq.getResultList();
        em.close();
        return ret;
    }

    private static <T extends PersistableInterface> void store(T o){
        EntityManager em = getEntityManager();
        EntityTransaction et = em.getTransaction();
        et.begin();
        em.persist(o);
        et.commit();
        em.close();
    }

    private static <T extends PersistableInterface> void storeAll(List<T> l){
        EntityManager em = getEntityManager();
        EntityTransaction et = em.getTransaction();
        et.begin();
        for(T o: l){
            em.persist(o);
        }
        et.commit();
        em.close();
    }

    /**
     * Updates an unmanaged {@code Entity}
     * @param o
     * @param <T>
     */
    private static <T extends PersistableInterface> void update(T o){
        EntityManager em = getEntityManager();
        EntityTransaction et = em.getTransaction();
        em.merge(o);
        et.commit();
        em.close();
    }



}
